//
//  KZWaveView.m
//  听说弱点强化训练
//
//  Created by 朱凯 on 2018/10/19.
//  Copyright © 2018年 盛超. All rights reserved.
//

#import "KZWaveView.h"


@interface KZWaveView ()

@property (nonatomic, strong) CADisplayLink *waveDisplaylink;

@property (nonatomic, strong) CAShapeLayer  *firstWaveLayer;
@property (nonatomic, strong) CAShapeLayer  *secondWaveLayer;

@end

@implementation KZWaveView {
    
    CGFloat _waterWaveHeight;
    CGFloat _waterWaveWidth;
    CGFloat _offsetX;           // 波浪x位移
    CGFloat _currentWavePointY; // 当前波浪上市高度Y（高度从大到小 坐标系向下增长）
    
    float _variable;            // 可变参数 更加真实 模拟波纹
    BOOL _increase;             // 增减变化
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        self.layer.masksToBounds  = YES;
        [self setUp];
    }
    
    return self;
}

- (void)setFrame:(CGRect)frame {
    
    [super setFrame:frame];
    _waterWaveHeight = self.frame.size.height/2;
    _waterWaveWidth  = self.frame.size.width;
    if (_waterWaveWidth > 0) {
        _waveCycle =  1.29 * M_PI / _waterWaveWidth;
    }
    
    if (_currentWavePointY <= 0) {
        _currentWavePointY = self.frame.size.height;
    }
}

- (void)setUp
{
    _waterWaveHeight = self.frame.size.height/2;
    _waterWaveWidth  = self.frame.size.width;
    _firstWaveColor = [UIColor.whiteColor colorWithAlphaComponent:0.5];
    _secondWaveColor = [UIColor.whiteColor colorWithAlphaComponent:0.2];
    
    _waveGrowth = 2;
    _waveSpeed = 0.1/M_PI;
    _waveAmplitude = 10;
    _waveAmplitudeDynamic = true;
    
    [self resetProperty];
}

- (void)resetProperty
{
    _currentWavePointY = self.frame.size.height;
    
    _variable = 1.6;
    _increase = NO;
    
    _offsetX = 0;
}

- (void)setFirstWaveColor:(UIColor *)firstWaveColor
{
    _firstWaveColor = firstWaveColor;
    _firstWaveLayer.fillColor = firstWaveColor.CGColor;
}

- (void)setSecondWaveColor:(UIColor *)secondWaveColor
{
    _secondWaveColor = secondWaveColor;
    _secondWaveLayer.fillColor = secondWaveColor.CGColor;
}

- (void)setPercent:(CGFloat)percent
{
    if (percent < _percent) {
        // 下降
        _waveGrowth = _waveGrowth > 0 ? -_waveGrowth : _waveGrowth;
    }else if (percent > _percent) {
        // 上升
        _waveGrowth = _waveGrowth > 0 ? _waveGrowth : -_waveGrowth;
    }
    _percent = percent;
    
}
- (void)setPercent:(CGFloat)percent animation:(BOOL)isAnimation {
    
    if (percent < _percent) {
        // 下降
        _waveGrowth = _waveGrowth > 0 ? -_waveGrowth : _waveGrowth;
    }else if (percent > _percent) {
        // 上升
        _waveGrowth = _waveGrowth > 0 ? _waveGrowth : -_waveGrowth;
    }
    _percent = percent;
    
    if (!isAnimation) {
        _currentWavePointY = 2 * _waterWaveHeight *(1-_percent);
    }
}

-(void)startWave{
    
    if (_firstWaveLayer == nil) {
        // 创建第一个波浪Layer
        _firstWaveLayer = [CAShapeLayer layer];
        _firstWaveLayer.fillColor = _firstWaveColor.CGColor;
        [self.layer addSublayer:_firstWaveLayer];
    }
    
    if (_secondWaveLayer == nil) {
        // 创建第二个波浪Layer
        _secondWaveLayer = [CAShapeLayer layer];
        _secondWaveLayer.fillColor = _secondWaveColor.CGColor;
        [self.layer addSublayer:_secondWaveLayer];
    }
    
    if (_waveDisplaylink == nil) {
        // 启动定时调用
        _waveDisplaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(getCurrentWave:)];
        [_waveDisplaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
    }
    
}

- (void)reset
{
    [self stopWave];
    [self resetProperty];
    
    if (_firstWaveLayer) {
        [_firstWaveLayer removeFromSuperlayer];
        _firstWaveLayer = nil;
    }
    
    if (_secondWaveLayer) {
        [_secondWaveLayer removeFromSuperlayer];
        _secondWaveLayer = nil;
    }
}

-(void)animateWave
{
    if (_increase) {
        _variable += 0.01;
    }else{
        _variable -= 0.01;
    }
    
    if (_variable<=1) {
        _increase = YES;
    }
    
    if (_variable>=1.6) {
        _increase = NO;
    }
    
    _waveAmplitude = _variable*5;
}

-(void)getCurrentWave:(CADisplayLink *)displayLink{
    
    if (_waveAmplitudeDynamic) {
        [self animateWave];
    }
    
    
    if ( _waveGrowth > 0 && _currentWavePointY > 2 * _waterWaveHeight *(1-_percent)) {
        // 波浪高度未到指定高度 继续上涨
        _currentWavePointY -= _waveGrowth;
    }else if (_waveGrowth < 0 && _currentWavePointY < 2 * _waterWaveHeight *(1-_percent)){
        _currentWavePointY -= _waveGrowth;
    }
    
    // 波浪位移
    _offsetX += _waveSpeed;
    
    [self setCurrentFirstWaveLayerPath];
    
    [self setCurrentSecondWaveLayerPath];
}

-(void)setCurrentFirstWaveLayerPath{
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat y = _currentWavePointY;
    CGPathMoveToPoint(path, nil, 0, y);
    for (float x = 0.0f; x <=  _waterWaveWidth ; x++) {
        // 正弦波浪公式
        y = _waveAmplitude * sin(_waveCycle * x + _offsetX) + _currentWavePointY;
        CGPathAddLineToPoint(path, nil, x, y);
    }
    
    CGPathAddLineToPoint(path, nil, _waterWaveWidth, self.frame.size.height);
    CGPathAddLineToPoint(path, nil, 0, self.frame.size.height);
    CGPathCloseSubpath(path);
    
    _firstWaveLayer.path = path;
    CGPathRelease(path);
}

-(void)setCurrentSecondWaveLayerPath{
    
    CGMutablePathRef path = CGPathCreateMutable();
    CGFloat y = _currentWavePointY;
    CGPathMoveToPoint(path, nil, 0, y);
    for (float x = 0.0f; x <=  _waterWaveWidth ; x++) {
        // 余弦波浪公式
        y = _waveAmplitude * cos(_waveCycle * x + _offsetX) + _currentWavePointY;
        CGPathAddLineToPoint(path, nil, x, y);
    }
    
    CGPathAddLineToPoint(path, nil, _waterWaveWidth, self.frame.size.height);
    CGPathAddLineToPoint(path, nil, 0, self.frame.size.height);
    CGPathCloseSubpath(path);
    
    _secondWaveLayer.path = path;
    CGPathRelease(path);
}

-(void)stopWave{
    if (_waveDisplaylink) {
        [_waveDisplaylink invalidate];
        _waveDisplaylink = nil;
    }
}

- (void)dealloc{
    [self reset];
}

@end
